﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using CTPAPI;
using CTP.Exceptions;
using CTP.Entitys;
using CTP.Utilty;

namespace CTP.Response
{
    /// <summary>
    /// 功能：实现上期API中的回调管理类，是上期API回调与客户系统回调的中转，
    ///       处理上期API的回推信息，处理铸成后，把上期API的回推信息转发到客户系统。
    ///       在会话Session中，初始化上期交易API的时候，需要把此类的实例注册到上期交易API中。
    /// 创建：陈粤雄 20120430
    /// </summary>
    internal class ResponseManager : CThostFtdcTraderSpiWrapper
    {
        #region 字段
        #endregion

        #region 属性
        /// <summary>
        /// 回调处理类的唯一实例
        /// </summary>
        public static ResponseManager Instance { get; private set; }
        /// <summary>
        /// 获取或设置向外提供的回调接口，
        /// </summary>
        public ICTPCallback CTPCallback { get; set; }
        /// <summary>
        /// 获取缓存合约与合约所在的市场的关联。当下单回调时，会在回调的信息中包含合约所属的市场。
        /// </summary>
        public ConcurrentDictionary<string, string> DictContractExchange { get; private set; }
        #endregion 

        #region 构造
        static ResponseManager()
        {
            Instance = new ResponseManager();
        }

        private ResponseManager()
        {
            DictContractExchange = new ConcurrentDictionary<string, string>();
        }
        #endregion

        #region 回报处理
        #region 连接成功通知

        void CThostFtdcTraderSpiWrapper.OnFrontConnected()
        {
            this.State = ChannelState.Connected;
            _connectEvent.Set();
            Logger.Instance.Debug(string.Format("Channel{0}上期柜台连接成功", ChannelID));

            if (this.Account != null) //连接登陆成功过,但是断开了,现在API自动重连成功
            {
                Thread t = new Thread(
                    () =>
                    {
                        this.LoginSync(this.Account);
                    }
                );
                t.IsBackground = true;
                t.Start();//回调线程不能被阻塞
            }
        }

        #endregion

        #region 连接断开通知

        void CThostFtdcTraderSpiWrapper.OnFrontDisconnected(int nReason)
        {
            this.IsLogined = false;
            this.State = ChannelState.Disconnected;
           Logger.Instance.WriteInfo(string.Format("Channel{1}与上期柜台连接断开,原因:{0}", nReason, ChannelID));
        }

        #endregion

        #region 登陆回报

        void CThostFtdcTraderSpiWrapper.OnRspUserLogin(CThostFtdcRspUserLoginFieldWrapper pRspUserLogin, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{0}登陆响应,requestID={1},FrontID={2},SessionID={3}", this.ChannelID, nRequestID, pRspUserLogin.FrontID, pRspUserLogin.SessionID));

            if (pRspInfo == null || pRspInfo.ErrorID == 0)
            {
                this.IsLogined = true;
                this.FrontID = pRspUserLogin.FrontID;
                this.SessionID = pRspUserLogin.SessionID;
            }
            _loginEvent.Set();//顺序不要倒

            if (!_dictInsCache.ContainsKey(nRequestID))
            {
                return;
            }
            InsBase ins = _dictInsCache[nRequestID];
            if (this.IsLogined)
            {
                this.Account = ins.Account;//保存
            }
            if (bIsLast)
            {
                _dictInsCache.Remove(nRequestID);
            }
            ReturnCode result = new ReturnCode();
            result.IsSuccess = this.IsLogined;
            if (pRspInfo != null)
            {
                result.ErrorCode = pRspInfo.ErrorID;
                result.ErrorMessage = pRspInfo.ErrorMsg;
            }
            ins.Session.RspChannel.RspValidateTradingAccount(result, ins.RequestId);
        }

        #endregion

        #region 登出回报

        void CThostFtdcTraderSpiWrapper.OnRspUserLogout(CThostFtdcUserLogoutFieldWrapper pUserLogout, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspUserLogout未处理");
        }

        #endregion

        #region 报单回报

        //报单错误(CTP拒绝)
        void CThostFtdcTraderSpiWrapper.OnRspOrderInsert(CThostFtdcInputOrderFieldWrapper pInputOrder, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{0}下单[CTP废单]响应,OrderRef={1}", this.ChannelID, pInputOrder.OrderRef));
            if (!_dictOrderCache.ContainsKey(pInputOrder.OrderRef))
            {
                Logger.Instance.Error(string.Format("Channel{0}未找到原始单,OrderRef={1}", this.ChannelID, pInputOrder.OrderRef));
                return;
            }
            InsOrderReq ins = (InsOrderReq)_dictOrderCache[pInputOrder.OrderRef];
            _dictOrderCache.Remove(pInputOrder.OrderRef);

            ReturnCode ret = new ReturnCode();
            ret.IsSuccess = false;
            if (pRspInfo != null)
            {
                ret.ErrorCode = pRspInfo.ErrorID;
                ret.ErrorMessage = pRspInfo.ErrorMsg;
            }

            Report rpt = new Report();
            rpt.Account = ins.Account.Account;
            rpt.OrderRef = ins.Order.OrderRef;
            rpt.OrderState = OrderState.Invalid;
            rpt.Note = ret.ToString();

            ins.Session.RspChannel.RspPlaceOrder(rpt, ret, ins.RequestId);
        }

        /// <summary>
        /// 报单错误(Exchange)
        /// </summary>
        void CThostFtdcTraderSpiWrapper.OnErrRtnOrderInsert(CThostFtdcInputOrderFieldWrapper pInputOrder, CThostFtdcRspInfoFieldWrapper pRspInfo)
        {
            Logger.Instance.Info(string.Format("Channel{0}下单[Exchange废单]响应,OrderRef={1}", this.ChannelID, pInputOrder.OrderRef));

            if (!_dictOrderCache.ContainsKey(pInputOrder.OrderRef))
            {
                Logger.Instance.Error(string.Format("Channel{0}未找到原始单,OrderRef={1}", this.ChannelID, pInputOrder.OrderRef));
                return;
            }
            InsOrderReq ins = (InsOrderReq)_dictOrderCache[pInputOrder.OrderRef];
            _dictOrderCache.Remove(pInputOrder.OrderRef);

            ReturnCode ret = new ReturnCode();
            ret.IsSuccess = false;
            if (pRspInfo != null)
            {
                ret.ErrorCode = pRspInfo.ErrorID;
                ret.ErrorMessage = pRspInfo.ErrorMsg;
            }
            Report rpt = new Report();
            rpt.Account = ins.Account.Account;
            rpt.OrderRef = ins.Order.OrderRef;
            rpt.OrderState = OrderState.Invalid;
            rpt.Note = ret.ToString();
            ins.Session.RspChannel.RspPlaceOrder(rpt, ret, ins.RequestId);
        }

        //报单、撤单指令已接受 (ctp or Exchange)
        void CThostFtdcTraderSpiWrapper.OnRtnOrder(CThostFtdcOrderFieldWrapper pOrder)
        {
            Logger.Instance.Info(
               string.Format("Channel{0}下单/撤单响应,OrderRef={1},ordersubmitstatus={2},orderstatus={3},ordersysid={4},message={5}",
               this.ChannelID,
               pOrder.OrderRef,
               (char)pOrder.OrderSubmitStatus,
               (char)pOrder.OrderStatus,
               pOrder.OrderSysID,
               pOrder.StatusMsg));

            //更新合约与交易所字典表
            DictContractExchange[pOrder.InstrumentID] = pOrder.ExchangeID;

            if (!_dictOrderCache.ContainsKey(pOrder.OrderRef))
            {
                Logger.Instance.Debug(string.Format("Channel{0}接收委托/撤单回报时,未找到原始请求,OrderRef={1},该响应不是由本channel发出的请求", this.ChannelID, pOrder.OrderRef));
                return;
            }

            InsBase ins = _dictOrderCache[pOrder.OrderRef];
            if (ins is InsOrderReq)
            {
                //收到回报,不要从临时字典中删除ins
                ReturnCode ret = new ReturnCode();
                ret.IsSuccess = true;
                ret.ErrorMessage = pOrder.StatusMsg;

                InsOrderReq insOrderReq = (InsOrderReq)_dictOrderCache[pOrder.OrderRef];
                OrderState state = FlagConvertor.FromTThostFtdcOrderStatus((TThostFtdcOrderStatus)pOrder.OrderStatus);
                insOrderReq.Order.OrderState = state;//更新原始单状态

                if (state == OrderState.Reported || //委托回报
                    (string.IsNullOrEmpty(pOrder.OrderSysID) && state == OrderState.Canceled) || //没有ordersysid且状态为已撤,为交易所拒绝报单
                    !string.IsNullOrEmpty(pOrder.OrderSysID) && state == OrderState.Unknow //有单号,状态未知的情况是已报
                    )
                {
                    insOrderReq.Order.OrderID = pOrder.OrderSysID.Trim();//更新原始单单号
                    if (state == OrderState.Unknow) //修正状态
                    {
                        state = OrderState.Reported;
                    }
                    insOrderReq.Order.OrderState = state;//更新原始单状态
                    insOrderReq.Order.TotalFilledQuantity = pOrder.VolumeTraded;//更新成交量

                    Report rpt = new Report();
                    rpt.Account = insOrderReq.Account.Account;
                    rpt.HandFlag = HandFlag.Hand;
                    rpt.Note = ret.ErrorMessage;
                    rpt.OrderID = insOrderReq.Order.OrderID;
                    rpt.OrderRef = insOrderReq.Order.OrderRef;
                    rpt.OrderState = insOrderReq.Order.OrderState;
                    rpt.FilledQuantity = insOrderReq.Order.TotalFilledQuantity;
                    //rpt.FilledPrice=?
                    rpt.SequenceNum = pOrder.SequenceNo.ToString();
                    rpt.TimeStamp = pOrder.InsertTime;

                    ins.Session.RspChannel.RspPlaceOrder(rpt, ret, ins.RequestId);
                }
                else if (state == OrderState.Canceled || state == OrderState.PartFilledAndCancelled)//撤单回报
                {
                    OrderStatus status = new OrderStatus();
                    status.Account = ins.Account.Account;
                    status.AvgFilledPrice = insOrderReq.Order.AvgFilledPrice;
                    status.OrderID = insOrderReq.Order.OrderID;
                    status.Size = insOrderReq.Order.Size;
                    status.State = insOrderReq.Order.OrderState;
                    status.TimeStamp = DateTime.Now.ToString("HH:mm:ss.fff");
                    status.TotalFilled = insOrderReq.Order.TotalFilledQuantity;

                    ins.Session.RspChannel.RspOrderStatus(status, ret, insOrderReq.RequestId);
                }
            }
            else if (ins is InsOrderCancel)
            {
               Logger.Instance.WriteInfo("委托回报/撤单回报中处理到InsOrderCancel");
                return;
            }
        }

        //成交回报、撤单回报
        void CThostFtdcTraderSpiWrapper.OnRtnTrade(CThostFtdcTradeFieldWrapper pTrade)
        {
            Logger.Instance.Info(string.Format("Channel{0}收到成交回报,OrderSysID={1},Volume={2},Price={3}", this.ChannelID, pTrade.OrderSysID, pTrade.Volume, pTrade.Price));
            if (!_dictOrderCache.ContainsKey(pTrade.OrderRef))
            {
                Logger.Instance.Debug(string.Format("Channel{0}收到不是本连接发出的成交回报,OrderSysID={1}", this.ChannelID, pTrade.OrderSysID));
                return;
            }
            InsBase ins = _dictOrderCache[pTrade.OrderRef];
            if (ins is InsOrderReq)
            {
                InsOrderReq orq = (InsOrderReq)ins;

                float oldFilledQuantity = orq.Order.TotalFilledQuantity;
                orq.Order.TotalFilledQuantity += pTrade.Volume;//更新报单的成交量
                orq.Order.AvgFilledPrice = (float)(oldFilledQuantity * orq.Order.AvgFilledPrice + pTrade.Volume * pTrade.Price) / orq.Order.TotalFilledQuantity;//更新均价
                orq.Order.OrderState = orq.Order.Size == orq.Order.TotalFilledQuantity ? OrderState.Filled : OrderState.PartFilled;//更新报单状态

                Report rpt = new Report();
                rpt.Account = orq.Order.Account;
                rpt.FilledPrice = (float)pTrade.Price;
                rpt.FilledQuantity = pTrade.Volume;
                rpt.HandFlag = orq.Order.HandFlag;
                rpt.OrderID = orq.Order.OrderID;
                rpt.OrderRef = orq.Order.OrderRef;
                rpt.OrderState = orq.Order.OrderState;
                rpt.SequenceNum = pTrade.SequenceNo.ToString();
                rpt.TimeStamp = pTrade.TradeTime;
                ins.Session.RspChannel.RspOrderFilled(rpt);

                OrderStatus status = new OrderStatus();
                status.Account = orq.Order.Account;
                status.AvgFilledPrice = orq.Order.AvgFilledPrice;
                status.OrderID = orq.Order.OrderID;
                status.Size = orq.Order.Size;
                status.State = orq.Order.OrderState;
                status.TimeStamp = pTrade.TradeTime;
                status.TotalFilled = orq.Order.TotalFilledQuantity;
                ins.Session.RspChannel.RspOrderStatus(status, ReturnCode.Success, ins.RequestId);
            }
            else if (ins is InsOrderCancel)
            {
               Logger.Instance.WriteInfo("成交回报收到InsOrderCancel");
                return;
            }
        }

        #endregion

        #region 撤单回报

        /// <summary>
        /// 撤单拒绝(CTP)
        /// </summary>
        void CThostFtdcTraderSpiWrapper.OnRspOrderAction(CThostFtdcInputOrderActionFieldWrapper pInputOrderAction, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{0}撤单[CTP废单]响应,OrderActionRef={1}", this.ChannelID, pInputOrderAction.OrderActionRef));
            if (!_dictOrderCache.ContainsKey(pInputOrderAction.OrderActionRef.ToString()))
            {
                Logger.Instance.Debug(string.Format("Channel{0}撤单[CTP废单]响应未找到原始单,OrderActionRef={1}", this.ChannelID, pInputOrderAction.OrderActionRef));
                return;
            }
            InsBase ins = _dictOrderCache[pInputOrderAction.OrderActionRef.ToString()];
            _dictOrderCache.Remove(pInputOrderAction.OrderActionRef.ToString());

            ReturnCode result = new ReturnCode();
            result.IsSuccess = false;
            if (pRspInfo != null)
            {
                result.ErrorCode = pRspInfo.ErrorID;
                result.ErrorMessage = pRspInfo.ErrorMsg;
            }
            ins.Session.RspChannel.RspCancelOrder(result, ins.RequestId);
        }

        //撤单错误(Exchange)
        void CThostFtdcTraderSpiWrapper.OnErrRtnOrderAction(CThostFtdcOrderActionFieldWrapper pOrderAction, CThostFtdcRspInfoFieldWrapper pRspInfo)
        {
            Logger.Instance.Info(string.Format("Channel{0}撤单[Exchange废单]响应,OrderActionRef={1}", this.ChannelID, pOrderAction.OrderActionRef));
            if (!_dictOrderCache.ContainsKey(pOrderAction.OrderActionRef.ToString()))
            {
                Logger.Instance.Debug(string.Format("Channel{0}撤单[Exchange废单]响应未找到原始单,OrderActionRef={1}", this.ChannelID, pOrderAction.OrderActionRef));
                return;
            }
            InsBase ins = _dictOrderCache[pOrderAction.OrderActionRef.ToString()];
            _dictOrderCache.Remove(pOrderAction.OrderActionRef.ToString());

            ReturnCode result = new ReturnCode();
            result.IsSuccess = false;
            if (pRspInfo != null)
            {
                result.ErrorCode = pRspInfo.ErrorID;
                result.ErrorMessage = pRspInfo.ErrorMsg;
            }
            ins.Session.RspChannel.RspCancelOrder(result, ins.RequestId);
        }

        #endregion

        #region 查报单状态/当日委托/历史委托 回报

        private Dictionary<int, List<Order>> _dictQryOrder = new Dictionary<int, List<Order>>();

        //查报单状态/当日委托/历史委托 回报
        void CThostFtdcTraderSpiWrapper.OnRspQryOrder(CThostFtdcOrderFieldWrapper pOrder, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            //如何来区分这么多查询类型呢?
            if (!_dictInsCache.ContainsKey(nRequestID))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}收到查委托时,未找到原始指令,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            if (
                !(pRspInfo == null || pRspInfo.ErrorID == 0))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}查委托失败,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            InsBase ins = _dictInsCache[nRequestID];
            if (ins.InsType == InsType.ORDER_STATATE) //查委托状态的
            {
                if (pOrder == null)
                {
                    return;
                }
                OrderStatus rsp = new OrderStatus();
                rsp.Account = ins.Account.Account;
                rsp.OrderID = pOrder.OrderSysID.Trim();
                rsp.Size = pOrder.VolumeTotalOriginal;
                rsp.State = FlagConvertor.FromTThostFtdcOrderStatus((TThostFtdcOrderStatus)pOrder.OrderStatus);
                rsp.TimeStamp = pOrder.UpdateTime;
                rsp.TotalFilled = pOrder.VolumeTraded;

                Logger.Instance.Info(string.Format("Channel{0}收到查委托单状态响应,requestid={1},OrderSysID={2},State={3}", this.ChannelID, nRequestID, rsp.OrderID, rsp.State));
                ins.Session.RspChannel.RspOrderStatus(rsp, ReturnCode.Success, ins.RequestId);
            }
            else if (ins.InsType == InsType.QRY_TODAY_ORDER)
            {
                if (!_dictQryOrder.ContainsKey(nRequestID))
                {
                    _dictQryOrder.Add(nRequestID, new List<Order>());
                }
                if (pOrder != null)
                {
                    List<Order> list = _dictQryOrder[nRequestID];
                    Order ord = new Order();
                    Contract crt = new Contract();
                    ord.Contract = crt;
                    list.Add(ord);

                    crt.Currency = Currency.RMB;
                    crt.Symbol = pOrder.InstrumentID;
                    crt.Description = pOrder.InstrumentID;
                    crt.Exchange = Exchange.CFFEX;//警告！需要找合适的方法来判断合约市场

                    ord.Account = pOrder.InvestorID;
                    ord.HandFlag = HandFlag.Hand;
                    ord.OrderID = pOrder.OrderSysID.Trim();
                    ord.Size = pOrder.VolumeTotalOriginal;
                    ord.OrderState = FlagConvertor.FromTThostFtdcOrderStatus((TThostFtdcOrderStatus)pOrder.OrderStatus);
                    ord.Side = FlagConvertor.FromTFtdcDirectionType((TFtdcDirectionType)pOrder.Direction);
                    ord.TotalFilledQuantity = pOrder.VolumeTraded;
                }
                if (bIsLast)
                {
                    List<Order> orders = _dictQryOrder[nRequestID];
                    _dictPosition.Remove(nRequestID);

                    ins.Session.RspChannel.RspTodayOrder(orders, null, ReturnCode.Success, ins.RequestId);
                }
            }

            if (bIsLast)
            {
                _dictInsCache.Remove(nRequestID);
            }
        }
        #endregion

        #region 查成交

        private Dictionary<int, List<Order>> _dictFilled = new Dictionary<int, List<Order>>();

        void CThostFtdcTraderSpiWrapper.OnRspQryTrade(CThostFtdcTradeFieldWrapper pTrade, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            if (!_dictInsCache.ContainsKey(nRequestID))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}收到查成交记录时,未找到原始指令,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            if (
                !(pRspInfo == null || pRspInfo.ErrorID == 0))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}查成交记录失败,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            InsBase ins = _dictInsCache[nRequestID];
            if (!_dictFilled.ContainsKey(nRequestID))
            {
                _dictFilled.Add(nRequestID, new List<Order>());
            }
            if (pTrade != null)
            {
                List<Order> list = _dictFilled[nRequestID];
                Order ord = new Order();
                Contract crt = new Contract();
                ord.Contract = crt;
                list.Add(ord);

                //填充
                crt.Currency = Currency.RMB;
                crt.Symbol = pTrade.InstrumentID;
                crt.Description = pTrade.InstrumentID;
                crt.SecType = ContractCategory.Futures;
                ord.Account = ins.Account.Account;
                ord.HandFlag = HandFlag.Hand;
                ord.Side = FlagConvertor.FromTFtdcDirectionType((TFtdcDirectionType)pTrade.Direction);
                ord.TotalFilledQuantity = pTrade.Volume;
                ord.Price = (float)pTrade.Price;
            }
            if (bIsLast)
            {
                List<Order> orders = _dictFilled[nRequestID];
                _dictFilled.Remove(nRequestID);
                _dictInsCache.Remove(nRequestID);

                ins.Session.RspChannel.RspTodayFilled(orders, null, ReturnCode.Success, ins.RequestId);
            }
        }

        #endregion

        #region 查持仓

        private Dictionary<int, List<Position>> _dictPosition = new Dictionary<int, List<Position>>();

        void CThostFtdcTraderSpiWrapper.OnRspQryInvestorPosition(CThostFtdcInvestorPositionFieldWrapper pInvestorPosition, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            if (!_dictInsCache.ContainsKey(nRequestID))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}收到查持仓回报时,未找到原始指令,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            if (!_dictPosition.ContainsKey(nRequestID))
            {
                _dictPosition.Add(nRequestID, new List<Position>());
            }
            List<Position> list = _dictPosition[nRequestID];
            Position p = new Position();
            list.Add(p);

            p.Account = pInvestorPosition.InvestorID;
            p.Symbol = pInvestorPosition.InstrumentID;
            p.Description = pInvestorPosition.InstrumentID;
            p.Currency = Currency.RMB;
            p.HandFlag = HandFlag.Hand;
            p.Side = FlagConvertor.FromTThostFtdcPosiDirection((TThostFtdcPosiDirection)pInvestorPosition.PosiDirection);
            p.PrevPosition = pInvestorPosition.YdPosition;
            p.AvailblePosition = pInvestorPosition.Position;
            p.TotalPosition = pInvestorPosition.Position;
            p.AvgCost = (float)pInvestorPosition.PositionCost;

            if (bIsLast)
            {
                InsBase ins = _dictInsCache[nRequestID];
                _dictInsCache.Remove(nRequestID);
                List<Position> retList = _dictPosition[nRequestID];
                _dictPosition.Remove(nRequestID);

                ins.Session.RspChannel.RspPosition(retList, ReturnCode.Success, ins.RequestId);
            }
        }

        #endregion

        #region 查询结算信息

        void CThostFtdcTraderSpiWrapper.OnRspQrySettlementInfoConfirm(CThostFtdcSettlementInfoConfirmFieldWrapper pSettlementInfoConfirm, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{1}查结算信息响应,requestID={0}", nRequestID, ChannelID));
            InsBase ins = _dictInsCache[nRequestID];
            if (bIsLast)
            {
                _dictInsCache.Remove(nRequestID);
            }
            ReturnCode result = new ReturnCode();
            result.IsSuccess = pRspInfo == null || pRspInfo.ErrorID == 0;
            ins.Session.RspChannel.RspSettlementInfo(result, ins.RequestId);
        }
        #endregion

        #region 确认投资者结算结果

        void CThostFtdcTraderSpiWrapper.OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmFieldWrapper pSettlementInfoConfirm, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{1}确认结算信息响应,requestID={0}", nRequestID, ChannelID));
            InsBase ins = _dictInsCache[nRequestID];
            if (bIsLast)
            {
                _dictInsCache.Remove(nRequestID);
            }
            ReturnCode result = new ReturnCode();
            result.IsSuccess = pRspInfo == null || pRspInfo.ErrorID == 0;
            ins.Session.RspChannel.RspSettlementInfoConfirm(result, ins.RequestId);
        }
        #endregion

        #region 请求查询资金账户

        void CThostFtdcTraderSpiWrapper.OnRspQryTradingAccount(CThostFtdcTradingAccountFieldWrapper pTradingAccount, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
            Logger.Instance.Info(string.Format("Channel{0}收到查帐户概览响应,requestid={1}", this.ChannelID, nRequestID));
            if (!_dictInsCache.ContainsKey(nRequestID))
            {
               Logger.Instance.WriteInfo(string.Format("Channel{0}收到查帐户概览响应时,未找到原始指令,requestid={1}", this.ChannelID, nRequestID));
                return;
            }
            InsBase ins = _dictInsCache[nRequestID];
            if (bIsLast)
            {
                _dictInsCache.Remove(nRequestID);
            }
            if (pRspInfo == null || pRspInfo.ErrorID == 0)//查询成功
            {
                AccountSummary summary = new AccountSummary();
                summary.Account = pTradingAccount.AccountID;
                summary.PreBalance = pTradingAccount.PreBalance - pTradingAccount.PreCredit - pTradingAccount.PreMortgage + pTradingAccount.Mortgage - pTradingAccount.Withdraw + pTradingAccount.Deposit;
                summary.RightsBalance = summary.PreBalance + pTradingAccount.CloseProfit + pTradingAccount.PositionProfit - pTradingAccount.Commission;
                summary.AvailableCapital = summary.RightsBalance - pTradingAccount.CurrMargin - pTradingAccount.FrozenMargin - pTradingAccount.FrozenCommission;
                summary.FrozenBalance = pTradingAccount.FrozenMargin;
                summary.Balance = summary.AvailableCapital + summary.FrozenBalance;
                summary.RequiredMargin = pTradingAccount.CurrMargin;

                ins.Session.RspChannel.RspAccountSummary(summary, ReturnCode.Success, ins.RequestId);
            }
            else
            {
                ReturnCode result = new ReturnCode();
                result.IsSuccess = false;
                if (pRspInfo != null)
                {
                    result.ErrorMessage = pRspInfo.ErrorMsg;
                    result.ErrorCode = pRspInfo.ErrorID;
                }
                ins.Session.RspChannel.RspAccountSummary(null, result, ins.RequestId);
               Logger.Instance.WriteInfo(string.Format("Channel{0}收到查帐户概览失败,requestid={1}", this.ChannelID, nRequestID));
            }
        }

        #endregion

        #region 未处理的回报

        void CThostFtdcTraderSpiWrapper.OnRspQryInstrument(CThostFtdcInstrumentFieldWrapper pInstrument, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInstrument未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspError(CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspError未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnHeartBeatWarning(int nTimeLapse)
        {
           Logger.Instance.WriteInfo("回调方法OnHeartBeatWarning未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspParkedOrderAction(CThostFtdcParkedOrderActionFieldWrapper pParkedOrderAction, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspParkedOrderAction未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspParkedOrderInsert(CThostFtdcParkedOrderFieldWrapper pParkedOrder, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspParkedOrderInsert未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryContractBank(CThostFtdcContractBankFieldWrapper pContractBank, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryContractBank未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryDepthMarketData(CThostFtdcDepthMarketDataFieldWrapper pDepthMarketData, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryDepthMarketData未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryExchange(CThostFtdcExchangeFieldWrapper pExchange, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryExchange未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryInstrumentCommissionRate(CThostFtdcInstrumentCommissionRateFieldWrapper pInstrumentCommissionRate, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInstrumentCommissionRate未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryInstrumentMarginRate(CThostFtdcInstrumentMarginRateFieldWrapper pInstrumentMarginRate, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInstrumentMarginRate未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryInvestor(CThostFtdcInvestorFieldWrapper pInvestor, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInvestor未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryInvestorPositionCombineDetail(CThostFtdcInvestorPositionCombineDetailFieldWrapper pInvestorPositionCombineDetail, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInvestorPositionCombineDetail未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryInvestorPositionDetail(CThostFtdcInvestorPositionDetailFieldWrapper pInvestorPositionDetail, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryInvestorPositionDetail未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryNotice(CThostFtdcNoticeFieldWrapper pNotice, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryNotice未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryParkedOrder(CThostFtdcParkedOrderFieldWrapper pParkedOrder, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryParkedOrder未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryParkedOrderAction(CThostFtdcParkedOrderActionFieldWrapper pParkedOrderAction, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryParkedOrderAction未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQrySettlementInfo(CThostFtdcSettlementInfoFieldWrapper pSettlementInfo, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQrySettlementInfo未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryTradingCode(CThostFtdcTradingCodeFieldWrapper pTradingCode, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryTradingCode未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryTradingNotice(CThostFtdcTradingNoticeFieldWrapper pTradingNotice, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryTradingNotice未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQryTransferBank(CThostFtdcTransferBankFieldWrapper pTransferBank, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQryTransferBank未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspQueryMaxOrderVolume(CThostFtdcQueryMaxOrderVolumeFieldWrapper pQueryMaxOrderVolume, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspQueryMaxOrderVolume未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspRemoveParkedOrder(CThostFtdcRemoveParkedOrderFieldWrapper pRemoveParkedOrder, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspRemoveParkedOrder未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspRemoveParkedOrderAction(CThostFtdcRemoveParkedOrderActionFieldWrapper pRemoveParkedOrderAction, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspRemoveParkedOrderAction未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspTradingAccountPasswordUpdate(CThostFtdcTradingAccountPasswordUpdateFieldWrapper pTradingAccountPasswordUpdate, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspTradingAccountPasswordUpdate未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspTransferBankToFuture(CThostFtdcTransferBankToFutureRspFieldWrapper pTransferBankToFutureRsp, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspTransferBankToFuture未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspTransferFutureToBank(CThostFtdcTransferFutureToBankRspFieldWrapper pTransferFutureToBankRsp, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspTransferFutureToBank未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspTransferQryBank(CThostFtdcTransferQryBankRspFieldWrapper pTransferQryBankRsp, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspTransferQryBank未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspTransferQryDetail(CThostFtdcTransferQryDetailRspFieldWrapper pTransferQryDetailRsp, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspTransferQryDetail未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRspUserPasswordUpdate(CThostFtdcUserPasswordUpdateFieldWrapper pUserPasswordUpdate, CThostFtdcRspInfoFieldWrapper pRspInfo, int nRequestID, bool bIsLast)
        {
           Logger.Instance.WriteInfo("回调方法OnRspUserPasswordUpdate未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRtnInstrumentStatus(CThostFtdcInstrumentStatusFieldWrapper pInstrumentStatus)
        {
           Logger.Instance.WriteInfo("回调方法OnRtnInstrumentStatus未处理");
        }

        void CThostFtdcTraderSpiWrapper.OnRtnTradingNotice(CThostFtdcTradingNoticeInfoFieldWrapper pTradingNoticeInfo)
        {
           Logger.Instance.WriteInfo("回调方法OnRtnTradingNotice未处理");
        }

        #endregion
        #endregion
    }
}
